Windows opened by Tools Plus are identical to those opened by conventional Macintosh toolbox routines, except that they and the objects on them inherit the benefit of being automatically maintained by Tools Plus. Some additional features can also be found in Tools Plus windows that aren’t available in ordinary windows.
Before you can use a window, you must first open it by using the WindowOpen procedure. Each window is referenced by a unique window number. This number is specified when the window is opened, and refers to the specific window until that window is closed. After a window has been opened, your application can create objects in it, such as buttons, lists, scroll bars, editing fields, etc. These items are detailed later in this manual.
At any time, your application can obtain information about a window’s location, size, and status by using the WindowStatus routine.
You can use Tools Plus’s windows instead of creating alerts and dialogs with ResEdit. Tools Plus can provide all the functionality that real alerts and dialogs can, and more. See the section on Dynamic Alerts for more information about using alert boxes.
When a window is no longer required, it is closed by the WindowClose procedure, which releases the memory used by the window’s buttons, scroll bars, editing fields, custom controls, and list boxes.
Note: Much of the Macintosh’s power lies in QuickDraw, the part of the
toolbox that allows Macintosh programmers to perform highly
complex graphic operations quickly and easily. There is an entire
chapter in Volume I of Inside Macintosh dedicated to QuickDraw
that is compulsory reading for all Macintosh programmers. The
chapter on the Font Manager (Inside Macintosh Volume I) explains
how to display text on a window.
Title Bar, Close box, and Zoom box
``````````````````````````````````
Any window that contains a title bar can have a “close box” and/or a “zoom box.” The close box, when clicked by the user, instructs your application to close the window.
A window containing a zoom box (the box in the right side of the title bar) has two different states: [1] the standard state, and [2] the user state. The user can change the window’s size and/or location, thereby defining the user state. When the zoom box is clicked, the window automatically “zooms” back to the standard state (which can be defined by your application). Clicking the zoom box again reverts to the user state.
Your application can define the minimum and maximum size of a window by using SetWindowSizeLimits. It can also define the size and position the window will assume when the zoom box is clicked by using the SetWindowZoom procedure. GetWindowZoom can be used to retrieve the window’s current size and location, as well as the size and location that will be assumed when the zoom box is clicked.
Any window with a title bar can be re-positioned by dragging it with the mouse. An inactive window can be dragged without being activated by holding the Command key down during the drag. By default, these windows can be dragged anywhere on the screen providing that the top of the window does not “slip beneath” the menu bar, and the cursor does not come within 4 pixels of the bottom, left, or right side of the screen while dragging the window to its new location. Your application can confine the dragging to a specified area by using the SetCursDragBounds procedure. A window’s title can be changed by the WindowTitle procedure.
Size Box
````````
A size box is a square located in the bottom right corner of a sizable document window. The user can change a window’s size by dragging the size box. By default, the window can be sized horizontally to any width from a minimum 120 pixels to the full width of the screen. Vertically, the window can be sized to any height from a minimum of 68 pixels to the full height of the screen (excluding the height of the menu bar). When the window is opened, the default sizing limits for the window are automatically adjusted to the window’s size. For example, the minimum size will never be larger than the window’s dimensions, and the maximum size will never be smaller than the window’s dimensions. These sizing limits can be changed by the SetWindowSizeLimits procedure.
Maximum Number of Open Windows
``````````````````````````````
The maximum number of windows that can be opened simultaneously is dictated by the InitToolsPlus procedure. Note that each potential window consumes some memory even if it is never used during the course of your application.
Active Window
`````````````
The active window, in all cases, is the front most window. It is the window that will be acted upon whenever the user types, gives commands, or does whatever is appropriate to the application being used. Note that the active window may be a desk accessory. Since desk accessories are handled automatically by Tools Plus, you only need to be concerned about your own windows. In Pascal terms, the active window’s WindowPtr is represented by the global constant FrontWindow. Your application can activate a window by using ActivateWindow, and it can determine the active window’s number by using ActiveWindowNumber.
Current Window
``````````````
The current window is the target of actions that occur within your application such as creating buttons or editing fields. Usually, the current window is the same as the active window, however there are times when it is desirable to affect a window without activating it. An example of this is when a window needs to be refreshed. This occurs when a window is obscured by another object on the screen. When the window is no longer obscured, the newly revealed section must be re-drawn or “refreshed.”
The CurrentWindow procedure can be used to make any of your application’s windows the “current” window. When work on the window is completed, it’s good form to make the active window current. This is done by using the CurrentWindowReset procedure. Your application can also determine the current window’s number by using CurrentWindowNumber. In Pascal terms, the current window’s WindowPtr is represented by the global constant thePort, which is the current grafPort.
Modal Windows
`````````````
When a window is modal, clicking the mouse outside the window results in a beep. This means that all interaction is restricted to the modal window until that window is closed. Pull-down menus can’t be selected, nor can their command-key equivalents.
When using MultiFinder or System 7 (or higher), modal windows behave differently: they can be modal for the current application, or for all applications. The standard dialog box (of dBoxProc type) keeps you in the current application by preventing you from switching to the Finder or other applications, or by launching a new application. All other modal windows, however, allow you to switch to the Finder or other applications (by clicking on one of their objects), and to launch a new application (by double-clicking it or one of its files). They do not, however, let you select menu items or click other windows within the same application. This is consistent with System 7’s modal dialog that is displayed while copying a file.
Global and Local Co-ordinates
`````````````````````````````
There are two co-ordinate systems that are used when creating Tools Plus objects: global and local. Global co-ordinates are relative to the main monitor where the upper left corner is point 0,0. Local co-ordinates are relative to the current window where the window’s upper left corner is point 0,0. The co-ordinate numbers increase when moving right or down, and decrease when moving left or up.
The Macintosh toolbox has a global variable called screenBits.bounds that is a rectangle defining the boundary of the Macintosh’s screen in global co-ordinates. You may want to use this variable to help you define a window’s maximum size, dragging limits, and zooming co-ordinates.
Details regarding global and local co-ordinates and screenBits.bounds can be found in Volume I of Inside Macintosh.
Handling Windows
````````````````
Much of the control exercised over windows is performed by your application. The PollSystem routine is used to constantly inquire about any requests the system may have. Some of these requests must be acted upon, such as refreshing a window. Other requests may be interpreted by your application, such as the user clicking in a window’s close box, or clicking in another window. These facets are all detailed by PollSystem. PollSystem automatically handles such chores as sizing, dragging, and zooming windows.
If your application will be drawing in color, see the “Color Drawing & Multiple Monitors” section later in this manual.
Window specifies the window that is to be opened. Once a window is opened, it will be referenced by this window number. If a window using the same window number is already open, it is closed, then a new window is opened as specified by the parameters in the WindowOpen procedure, thereby re-using the window number. The newly opened window becomes “active” (front-most and highlighted as such) and “current” (action pertaining to graphics, text, buttons, scroll bars, etc. occurs in this window). Tools Plus allows up to 50 windows to be open simultaneously, however, this limit can be reduced when InitToolsPlus initializes Tools Plus.
Left, top, right, and bottom define a rectangle in global co-ordinates that specifies the window’s size and location. These parameters can be seen as two corners; the upper left-hand corner (left,top) and the bottom right-hand corner (right,bottom). Some useful things to remember about sizing your window are:
• The co-ordinates you specify define the usable area. The window’s
outline and shadow are drawn outside these co-ordinates.
• If a document window has a right and/or bottom scroll bar
(documentProc type), 15 pixels of the usable area will be used up by
the width of the scroll bar.
• Windows with a title bar will use an additional 19 pixels above the
window’s top co-ordinate to draw the title bar.
• The menu bar takes up 20 pixels, so no window should have a top co-
ordinate which is less than 20.
The Title parameter is the window’s title. Note that some windows do not have a title. In this case, the title parameter may be passed as a null string (‘’).
ProcID is the window definition ID, which specifies a window’s appearance and implies certain behavior. A documentProc, for instance, is sizable whereas an rDocProc is used for “desk accessory like” windows. Below are the six (6) standard window definitions.
documentProc Standard, sizable document window (has a grow box)
noGrowDocProc Standard document window that can’t be re-sized
rDocProc Rounded-corner window, like the calculator
dBoxProc Standard dialog window (with border, modal)
plainDBox Plain dialog box with no border
altDBoxProc Plain dialog box with a drop-shadow
DocumentProc is a standard document window with a grow box (note that unlike ordinary Macintosh windows, the vertical and horizontal lines extending from the grow box are not drawn). NoGrowDocProc is exactly the same except it does not contain a grow box. The dBoxProc, plainDBox and altDBoxProc IDs resemble alert or dialog boxes. They cannot contain a title or size box. The rDocProc window is used primarily for desk accessories. It contains no size box. To include a “zoom box” in either the documentProc or noGrowDocProc type windows, add the constant ZoomBox to the value of the ProcID (i.e. documentProc + ZoomBox).
The goAwayFlag indicates if a “close box” is to be drawn. Close boxes are only drawn in the DocumentProc, noGrowDocProc and rDocProc windows shown above. The two constants that can be used for this flag are GoAway and NoGoAway.
The modalFlag indicates if the window is “modal” or not. When a modal window is open, clicking outside the window results in a beep. This means that all interaction is restricted to the modal window until that window is closed. The two constants that can be used for this flag are Modal and notModal.
Also see: WindowOpenRect.
CONST {Window definition IDs }
documentProc =0; {standard document window with size box }
dBoxProc =1; {alert box or modal dialogue box }
plainDBox =2; {plain box (usually modal) }
altDBoxProc =3; {plain box with shadow (usually modal) }
{“Go away” indicators… }
goAway =true; {create “close” box }
noGoAway =false; {do not create “close” box }
{“Modal window” indicators }
Modal =true; {window is modal }
notModal =false; {window is modeless }
Warning: When you open a window, make sure that the co-ordinates are
such that at least part of the window’s title bar is visible.
Don’t open an “off-screen” window.
Note: Although it is programatically possible, you should not open or
close other windows when a modal window is active. The only
exception to this is the use of another modal window as an “Alert”
WindowOpenRect is identical to the WindowOpen procedure, except that it accepts the Bounds rectangle in place of the individual left, top, right and bottom co-ordinates.
The WindowClose procedure closes a window that was opened by WindowOpen. The window immediately behind the newly closed window (if one exists) becomes active and current.
Window specifies the window number that is closed. If the specified window is not open, WindowClose does nothing.
When a window is closed, it automatically releases the memory that was consumed by its associated buttons, scroll bars, editing fields, list boxes, and custom controls.
The specified window is brought to the front most position and becomes “active” and “current.” Window specifies the window number that is to be activated. If the specified window is already “active,” ActivateWindow ensures that it is also the “current” window. If the window is not open, ActivateWindow does nothing.
A window will normally be activated only in response to a doChgWindow event that is reported during polling. Another possible use is if your application has a “Window” menu that lets the user activate a window from a menu. Don’t mysteriously activate an inactive window.
Make a window the current window without activating it.
pascal void CurrentWindow (int Window);
procedure CurrentWindow(Window: INTEGER);
Subsequent window related operations such as drawing, and creating fields, buttons, scroll bars, etc., will occur in the specified window without making it the “active” window. This routine is used to redirect your application’s actions to a window other than the active one.
Window specifies the window number in which subsequent window related operations will occur. If the specified window is not open, CurrentWindow does nothing.
The CurrentWindowReset procedure resets window operations back to the “active” window making the active window current too. You should get into the habit of leaving the active window current. It makes debugging much simpler.
Reset the “current” window to be the same as the “active” window.
pascal void CurrentWindowReset(void);
procedure CurrentWindowReset;
Subsequent window related operations such as drawing, and creating fields, buttons, scroll bars, etc., will occur in the “active” window. This procedure nullifies the effect of the CurrentWindow procedure making the “active” window current also.
The WindowTitle procedure changes the title for an open window, regardless if it is active or not. It only affects windows that bear titles (documentProc, noGrowDocProc, and rDocProc). There is no effect on windows that do not display titles (dBoxProc, plainDBox, and altDBoxProc).
Window specifies the window number in which the title is to be changed. The specified window does not have to be the “active” window, however, the window must be opened to display the title. “Hidden” windows will display the new title once they become visible. If the window is not open, WindowTitle does nothing.
Left, top, right, and bottom define a rectangle in global co-ordinates that determines the cursor’s “window dragging” boundary. These parameters can be seen as two corners; the upper left-hand corner (left,top) and the bottom right-hand corner (right,bottom). SetCursDragBounds affects only the current window. If the specified window is not open, or if the enclosing rectangle is empty (i.e. left is greater than right, or top is greater than bottom), SetCursDragBounds does nothing.
By default, a window can be dragged anywhere on the screen providing that the top of the window does not “slip beneath” the menu bar, and the cursor does not come within 4 pixels of the bottom, left, or right side of the screen. This effectively prevents a window from being dragged right off the desk top. By using SetCursDragBounds, you can prevent a window from overlapping others, or allow it to be repositioned without having part of it dragged off the screen.
MinHoriz specifies the minimum width (in pixels) the window may attain when being sized.
MinVert specifies the minimum height (in pixels) the window may attain when being sized.
MaxHoriz specifies the maximum width (in pixels) the window may attain when being sized.
MaxVert specifies the maximum height (in pixels) the window may attain when being sized.
SetWindowSizeLimits affects only the current window. If the current window is not a Tools Plus window, SetWindowSizeLimits does nothing. The minimum and maximum limits imposed on a window are automatically adjusted (if necessary) to ensure that the window current size does not exceed the adjusted limits. For example, if the minHoriz limit is set to 100 pixels and the window is currently 90 pixels wide (10 pixels smaller than the specified minimum width), minHoriz will be adjusted to 90 pixels. The same applies if the maximum limit is exceeded by the window’s current dimensions.
By setting these limits, it is possible to allow a window to be sized horizontally or vertically only.
Set a window’s standard co-ordinates and user co-ordinates that will be effected when the window’s “zoom box” is clicked.
pascal void SetWindowZoom (Rect *userRect, Rect *stdRect);
procedure SetWindowZoom(userRect, stdRect: RECT);
A window containing a zoom box has two different states: [1] the standard state, and [2] the user state. The user can change the window’s size and/or location, thereby defining the user state. When the zoom box is clicked, the window “zooms” back to the standard state (which, by default, is the window’s co-ordinates when it was first opened). Clicking the zoom box again reverts to the user state.
Sometimes it is desirable to have the standard state and/or user state something other than the window’s initial co-ordinates. SetWindowZoom sets either or both of these. The window’s current co-ordinates become the user state. It is good form to call SetWindowZoom immediately after opening a window.
UserRect defines a rectangle in global co-ordinates that determines the window’s user co-ordinates. If the current window is not a Tools Plus window, if the current window has no zoom box, or if an empty rectangle is specified, the user co-ordinates are not set.
StdState defines a rectangle in global co-ordinates that determines the window’s standard co-ordinates. If the current window is not a Tools Plus window, if the current window has no zoom box, or if an empty rectangle is specified, the standard co-ordinates are not set.
Warning: When you set the user and standard co-ordinates, make sure that
they are such that at least part of the window’s title bar is
visible to allow dragging the window back into view (don’t zoom
to an “off-screen” window). Ideally, the zoom box should
A window containing a zoom box has two different states: [1] the standard state, and [2] the user state. The user can change the window’s size and/or location, thereby defining the user state. When the zoom box is clicked, the window “zooms” back to the standard state (which, by default, is the window’s co-ordinates when it was first opened). Clicking the zoom box again reverts to the user state.
UserRect defines the window’s user state in the screen’s global co-ordinates.
StdRect defines the window’s standard state in the screen’s global co-ordinates.
GetWindowZoom gets the values for the current window. If the current window is not a Tools Plus window, or if the current window has no zoom box, the userRect and StdRect rectangles will be undefined. This procedure is useful if you want to save both states as part of the document. When the document is opened, a window could be created using the userRect co-ordinates, and the user and standard state can be set by using the SetWindowZoom procedure.
procedure WindowStatus(Window: INTEGER; var Status: TPWindowStatus);
The WindowStatus procedure returns the current status of any Tools Plus window, whether it is open or closed.
Window is the window number of a Tools Plus window. Window must be less than or equal to MaxWindows as defined by InitToolsPlus. If it is not, the Status record will be initialized to “false” and 0 values. MaxWindows defines the maximum number of Tools Plus windows that may be open at any time.
The Status record contains information about the Tools Plus window indicated by the Window value. The record is defined as such:
struct TPWindowStatus {
Boolean Open; /*Is the window open? */
Boolean Active; /*Is this the active window? */
Boolean Current; /*Is this the current window? */
Boolean Front; /*Is this the frontmost Tools Plus window? */
/* (which may be inactive) */
Point Size; /*Size in pixels (.h=horizontal, .v=vertical) */
Point Where; /*Location of top-left corner in global co-ords*/
};
typedef struct TPWindowStatus TPWindowStatus;
TPWindowStatus = record
Open: BOOLEAN; {is the window open? }
Active: BOOLEAN; {is this the active window? }
Current: BOOLEAN; {is this the current window? }
Front: BOOLEAN; {is this the front most Tools Plus window?}
{ which may not be inactive) }
Size: point; {size in pixels (.h=width, .v=height) }
Where: point {location of top-left corner in global co-}
end; {ordinates }
Open indicates if the specified window is open.
Active indicates if the specified window is active. A Tools Plus window will not be active under any of the following conditions:
• the window is not open
• another window is open in front of the specified window
• the active window is a desk accessory
Current indicates if the specified window is the current window. Current and active will be the same unless you used the CurrentWindow procedure to change the current window number.
Front indicated if the specified window is the front most window in your application. On a Macintosh, the front most window is always the active window. However, for your application, the front most window will not be active under any of the following conditions:
• a desk accessory is active
• another application or the Finder is active (under MultiFinder or
System 7)
Size is the window’s current height and width in pixels, represented as a point. Size.h is the horizontal measurement (width), and Size.v is the vertical measurement (height). Both these values will be zero (0) if a window is not open. The vertical measurement does not include the height of the title bar.
Where is the location of the window’s top-left corner in global co-ordinates, represented as a point. Where.h is the horizontal co-ordinate, and Where.v is the vertical co-ordinate. Both these values will be zero (0) if the window is not open. Note that the title bar extends above the vertical co-ordinate.
This function returns the window number of the active (front most) window. A value of zero (0) will be returned if any of the following conditions occur:
• no windows are open
• the active window is a desk accessory
• another application or the Finder is active (under MultiFinder or
System 7)
Also see: CurrentWindowNumber and FirstWindowNumber.
This function returns the window number of the current window. This window will be the same as the active window unless you used the CurrentWindow procedure to change the current window. A value of zero (0) will be returned if any of the following conditions occur:
• no windows are open
• the current window is a desk accessory
• another application or the Finder is current (under MultiFinder or
System 7)
Also see: ActiveWindowNumber and FirstWindowNumber.
function WindowPointer(Window: INTEGER): WindowPtr;
This function returns a window pointer to a Tools Plus window regardless if it is open or not.
Window is the window number of a Tools Plus window. Window must be less than or equal to MaxWindows as defined by InitToolsPlus. If it is not, nil will be returned.